package com.Practice.estore.service;

import com.Practice.estore.model.Product;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.*;
import java.util.Properties;

/**
 * 商品服务类，负责商品相关的业务逻辑
 * 支持数据持久化到文件，路径通过配置文件管理，并提供备份功能
 */
public class ProductService {

    // 使用Map存储商品数据，key是商品ID，value是商品对象
    private final Map<String, Product> productData = new HashMap<>();

    // 数据文件路径（从配置文件读取）
    private String dataFilePath;

    // 配置文件名称
    private static final String CONFIG_FILE = "config.properties";

    /**
     * 构造函数，初始化商品数据
     * 优先从文件加载数据，如果文件不存在则使用默认数据
     */
    public ProductService() {
        // 加载配置文件
        loadConfig();

        // 最先调用loadData()，尝试从文件加载数据
        if (!loadData()) {
            // 如果加载失败（比如文件不存在），使用默认数据
            initializeDefaultData();
        }
    }

    /**
     * 加载配置文件，读取数据文件路径
     */
    private void loadConfig() {
        Properties props = new Properties();
        File configFile = new File(CONFIG_FILE);

        if (!configFile.exists()) {
            System.out.println("配置文件不存在，使用默认路径: products.dat");
            dataFilePath = "products.dat";
            return;
        }

        try (InputStreamReader isr = new InputStreamReader(new FileInputStream(CONFIG_FILE), "UTF-8")) {
            // 使用InputStreamReader指定UTF-8编码读取配置文件
            props.load(isr);
            dataFilePath = props.getProperty("data.file.path", "products.dat");
            System.out.println("配置文件加载成功，数据文件路径: " + dataFilePath);
        } catch (IOException e) {
            System.out.println("加载配置文件失败: " + e.getMessage() + "，使用默认路径");
            dataFilePath = "products.dat";
        }
    }

    /**
     * 初始化默认商品数据（当没有数据文件时使用）
     */
    private void initializeDefaultData() {
        productData.put("p001", new Product("p001", "Java从入门到精通", 99.0, 100));
        productData.put("p002", new Product("p002", "高性能MySQL", 128.5, 50));
        productData.put("p003", new Product("p003", "颈椎康复指南", 45.0, 200));
        productData.put("p004", new Product("p004", "生发秘籍", 88.0, 0));
        productData.put("p005", new Product("p005", "Python编程", 79.0, 80));
        System.out.println("使用默认商品数据初始化完成");
    }

    /**
     * 从文件加载商品数据
     * @return 加载成功返回true，失败返回false
     */
    @SuppressWarnings("unchecked")
    public boolean loadData() {
        File file = new File(dataFilePath);
        if (!file.exists()) {
            System.out.println("数据文件不存在，将使用默认数据");
            return false;
        }

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(dataFilePath))) {
            // 从文件读取Map对象
            Map<String, Product> loadedData = (Map<String, Product>) ois.readObject();
            productData.clear();
            productData.putAll(loadedData);
            System.out.println("商品数据加载成功，共加载 " + productData.size() + " 个商品");
            return true;
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("加载商品数据失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 保存商品数据到文件
     * @return 保存成功返回true，失败返回false
     */
    public boolean saveData() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(dataFilePath))) {
            // 将整个Map对象写入文件
            oos.writeObject(productData);
            System.out.println("商品数据保存成功，共保存 " + productData.size() + " 个商品到 " + dataFilePath);
            return true;
        } catch (IOException e) {
            System.out.println("保存商品数据失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 备份数据文件
     * 使用基础字节流和缓冲区进行文件复制
     * @return 备份成功返回true，失败返回false
     */
    public boolean backupData() {
        File sourceFile = new File(dataFilePath);
        if (!sourceFile.exists()) {
            System.out.println("源数据文件不存在，无法备份");
            return false;
        }

        String backupFilePath = dataFilePath + ".bak";
        File backupFile = new File(backupFilePath);

        // 使用基础的FileInputStream和FileOutputStream进行文件复制
        try (FileInputStream fis = new FileInputStream(sourceFile);
             FileOutputStream fos = new FileOutputStream(backupFile)) {

            // 创建缓冲区，大小为1KB
            byte[] buffer = new byte[1024];
            int bytesRead;

            // 循环读取源文件数据到缓冲区，然后写入备份文件
            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }

            System.out.println("数据文件备份成功: " + backupFilePath);
            System.out.println("备份文件大小: " + backupFile.length() + " 字节");
            return true;

        } catch (IOException e) {
            System.out.println("备份数据文件失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 获取所有商品列表
     * @return 商品列表
     */
    public List<Product> getAllProducts() {
        return new ArrayList<>(productData.values());
    }

    /**
     * 根据ID查找商品
     * @param id 商品ID
     * @return 找到的商品对象，如果不存在则返回null
     */
    public Product findProductById(String id) {
        return productData.get(id);
    }

    /**
     * 获取当前使用的数据文件路径（用于测试和调试）
     * @return 数据文件路径
     */
    public String getDataFilePath() {
        return dataFilePath;
    }

    /**
     * 保存购物车数据
     */
    @SuppressWarnings("unused")
    public boolean saveCartData(Map<String, Integer> cart, String cartFilePath) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(cartFilePath))) {
            oos.writeObject(cart);
            System.out.println("购物车数据保存成功，共保存 " + cart.size() + " 种商品");
            return true;
        } catch (IOException e) {
            System.out.println("保存购物车数据失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 加载购物车数据
     */
    @SuppressWarnings({"unchecked", "unused"})
    public Map<String, Integer> loadCartData(String cartFilePath) {
        File file = new File(cartFilePath);
        if (!file.exists()) {
            return new HashMap<>();
        }

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(cartFilePath))) {
            Map<String, Integer> loadedCart = (Map<String, Integer>) ois.readObject();
            System.out.println("购物车数据加载成功，共加载 " + loadedCart.size() + " 种商品");
            return loadedCart;
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("加载购物车数据失败: " + e.getMessage());
            return new HashMap<>();
        }
    }
}